using System;
using System.Configuration;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Drawing;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Text;
using System.Text.RegularExpressions;

using Danser_AJAXEnabledWebApplication.User_Controls;
using Danser_AJAXEnabledWebApplication.Query_Popups;
using Danser_AJAXEnabledWebApplication.PageExt;
using Danser_Control.Managers;
using Danser_Entity.Entities;
using Danser_Entity.Queries.Data;
using Danser_Entity.Queries.Filters;

namespace Danser_AJAXEnabledWebApplication
{
    /// <summary>
    /// Page to perform queries comparing and display merged results of multiple tests
    /// </summary>
    public partial class Queries : TestDataDisplay//AbstractPage
    {
        #region Constants:

        //extended Row UI controls 
        private const String CONFIRMED_LABEL_ID = "confirmedLabel";
        private const String ANCHOR_LABEL_ID = "anchorLabel";

        #endregion

        #region Page Load:

        /// <summary>
        /// loads the page...
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected override void Page_Load(object sender, EventArgs e)
        {
            base.Page_Load(sender, e);

            if (!IsPostBack) //first time
            {
                //set columns in test info multi select according to the template
                _pageFormatter.DisplayColumnsTemplate(testInfoGridView, columnsMultiSelectList, 1, COLUMNS_TEMPLATE);

                //feed columns to results multi select list
                _pageFormatter.DisplayColumnsTemplate(testResultsGridView, testResultColumnsMultiSelectList, 0);

                //reset columns selection
                SetHeaderColumnSpan(testResultColumnsMultiSelectList);
            }

            Session[LoadQuery.SESSION_USER_ID] = ((Danser)Master).UserID;
        }

        #endregion

        #region Filter Tables Columns Panes:

        /// <summary>
        /// event handler
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void filterButton_Click(object sender, EventArgs e)
        {
            _pageFormatter.FilterColumnsByListSelection(testInfoGridView, columnsMultiSelectList);
        }

        /// <summary>
        /// event handler
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void testResultfilterButton_Click(object sender, EventArgs e)
        {
            _pageFormatter.FilterColumnsByListSelection(testResultsGridView, testResultColumnsMultiSelectList);

            SetHeaderColumnSpan(testResultColumnsMultiSelectList);
        }

        #endregion

        #region Filter Tables Rows:

        //Test Info Table
        /// <summary>
        /// event handler
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void filterTestInfoButton_Click(object sender, EventArgs e)
        {
            _pageFormatter.ToggleButtonText((Button)sender, new String[] { "Search Tests", "Hide Search" });

            HandleFilterRowsPanel(testInfoQueryPanel, testInfoQueryExpressionBuilder, TEST_INFO_SEARCH);
        }

        /// <summary>
        /// event handler
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void executeTestInfoQueryButton_Click(object sender, EventArgs e)
        {
            ExecuteSelect(testInfoObjectDataSource, testInfoQueryExpressionBuilder);
        }

        //Test Result Table
        /// <summary>
        /// event handler
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void filterTestResultButton_Click(object sender, EventArgs e)
        {
            _pageFormatter.ToggleButtonText((Button)sender, new String[] { "Search Results", "Hide Search" });

            HandleFilterRowsPanel(testResultQueryPanel, testResultQueryExpressionBuilder, TEST_RESULTS_SEARCH);
        }

        /// <summary>
        /// event handler
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void executeTestResultQueryButton_Click(object sender, EventArgs e)
        {
            ExecuteSelect(testResultsObjectDataSource, testResultQueryExpressionBuilder);

            //update query string for the save query popup
            IList<Condition> conditions = testResultQueryExpressionBuilder.getConditions(false);
            
            if (conditions == null)
                return;

            saveQueryButton.Enabled = true;

            RuleExpression rule = new RuleExpression(conditions);
            String parsedRule = rule.ConditionsToString(false);

            Session[SaveQuery.SESSION_USER_ID] = ((Danser)Master).UserID;
            Session[SaveQuery.SESSION_RULE_TO_SAVE_ID] = parsedRule;
        }

         #endregion

        #region Inner Row Control Handlers:

        /// <summary>
        /// event handler
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void displayRowLinkButton_Click(object sender, EventArgs e)
        {
            //get the containing row for testinfo index
            LinkButton button = sender as LinkButton;
            GridViewRow row = (button.Parent.Parent) as GridViewRow;

            String testInfoIndex = (String)testInfoGridView.DataKeys[row.RowIndex].Value;

            numericResultsDataPanel.Visible = 
                toggleDisplayModeButton.Text.Equals(RESULTS_DISPLAY_MODE[0]);

            graphResultsDataPanel.Visible = !numericResultsDataPanel.Visible; 
            
            //update graph control with test id
            try
            {
                _pageFormatter.SetGraphInput(QueriesGraphUserControl, testInfoIndex);
            }
            catch (Danser_Control.Exceptions.DanserGraphException graphException)
            {
                HandleGenericErrorPage(graphException);
            }
            
            //save testInfoIndex in session for further use
            Session[SELECTED_TEST_ID] = testInfoIndex;

            testResultQueryExpressionBuilder.
                SetInitialCondition(
                    new Condition(
                        Groups.Information,
                        TestInfoFields.TestInfoIndex.ToString(),
                        ComparingOperators.EQUALS,
                        testInfoIndex.ToString(),
                        BooleanOperators.AND,
                        false));

            //build initial rule
            GetTestResults(testInfoIndex, testResultsObjectDataSource, testResultsGridView);
        }

        #endregion

        #region DataGrid Handlers:

        /// <summary>
        /// Called for each data row to be bound to the datagrid
        /// </summary>
        /// <param name="sender">The data grid</param>
        /// <param name="e">contains the relvant row to bind data to</param>
        protected void testInfoGridView_RowDataBound(object sender, GridViewRowEventArgs e)
        {
            GridViewRow row = e.Row;
            if (row.RowType == DataControlRowType.DataRow)
            {
                //handle confirmed field
                FormatBooleanField(row, CONFIRMED_LABEL_ID);

                //handle anchor field
                FormatBooleanField(row, ANCHOR_LABEL_ID);

                String testIdx = (String)testInfoGridView.DataKeys[row.RowIndex].Value;

                try
                {
                    IList<ValidationTemplate> failedValidations = _validationManager.GetFailingTemplatesForTest(testIdx);

                    //handle validation status field
                    Label validationStatus = row.FindControl(VALIDATION_STATUS_LABEL_ID) as Label;
                    validationStatus.Text = failedValidations.Count == 0 ? "Passed" : "Failed";
                    validationStatus.ForeColor = failedValidations.Count == 0 ? Color.Green : Color.Red;

                    //handle failed validation field
                    TextBox failedValidationsTextBox = row.FindControl(VALIDATIONS_TEXT_BOX_ID) as TextBox;

                    failedValidationsTextBox.BackColor =
                        row.RowIndex % 2 == 0 ?
                        testInfoGridView.RowStyle.BackColor :
                        testInfoGridView.AlternatingRowStyle.BackColor;

                    _pageFormatter.FormatFailedValidations(failedValidationsTextBox, failedValidations);
                }
                catch (Exception exception)
                {
                    HandleGenericErrorPage(exception);
                }
            }
        }

        #endregion

        #region Helpers:

        /// <summary>
        /// Format display of a boolean field in a datagrid row
        /// </summary>
        /// <param name="row">The GridView row containing the field</param>
        /// <param name="fieldKey">The server control id</param>
        private void FormatBooleanField(GridViewRow row, String fieldKey)
        {
            Label label = (Label)row.FindControl(fieldKey);
            if (label != null)
            {
                label.Text =
                    label.Text.ToLower().Equals("false") ? "No" : "Yes";
                label.ForeColor =
                    label.Text.Equals("No") ? Color.Red : Color.Green;
            }
        }

        #endregion

        #region TestData Grid:

        /// <summary>
        /// event handler - toggle the results display modes for a selected test
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void toggleDisplayModeButton_Click(object sender, EventArgs e)
        {
            ToggleView(numericResultsDataPanel, graphResultsDataPanel, toggleDisplayModeButton, QueriesGraphUserControl);
        }

        /// <summary>
        /// handle creation event by adding the header row aggregating test results columns
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void testResultsGridView_RowCreated(object sender, GridViewRowEventArgs e)
        {
            if (e.Row.RowType == DataControlRowType.Header)
            {
                FormatResultsHeader(testResultsGridView);
            }
        }

        /// <summary>
        /// invoked when user wants to clear anchors display
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void removeAnchorButton_Click(object sender, EventArgs e)
        {
            Session[SelectAnchors.SESSION_SELECTED_ANCHORS] = new List<String>();
            RefreshAnchorsInGraph(QueriesGraphUserControl);

            removeAnchorButton.Enabled = false;
        }

        #endregion

        #region AbstractPage Implementation:

        /// <summary>
        /// returns true if the given permission has approved access for the page
        /// </summary>
        /// <param name="permissionlevel"></param>
        /// <returns></returns>
        protected override bool InnerValidatePermission(Danser_Entity.Entities.PermissionLevel permissionlevel)
        {
            //every one is allowed to access this page
            return true;
        }

        #endregion

        #region Popups:

        /// <summary>
        /// event handler - prepare data to pass to opened popup
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void loadQueryButton_Click(object sender, EventArgs e)
        {
            //added in case of future additional functionality
        }

        /// <summary>
        /// event handler - refresh update panel to insert selected query to results expression builder
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void loadQueryRefreshButton_Click(object sender, EventArgs e)
        {
            //update the expression builder with the selected query from popup
            String ruleString = Session[LoadQuery.SESSION_SELECTED_QUERY] as String;

            testResultQueryExpressionBuilder.DisplayRule(ruleString);
        }

        /// <summary>
        /// event handler - refresh update panel to insert selected anchor tests details to he graph builder
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void selectAnchorRefreshButton_Click(object sender, EventArgs e)
        {
            removeAnchorButton.Enabled = true;
            RefreshAnchorsInGraph(QueriesGraphUserControl);
        }

        #endregion

    }
}
